﻿using System.Runtime.Serialization;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Collections;
using System.Net;
using System.IO;
using System.Web;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;




namespace Givenchy
{
    /// <summary>
    /// 1,启动并自动开始
    /// 2.拨号，拨号成功后进入3，失败重播10次，都失败等30分钟
    /// 3，验证，不通过，进入2
    /// 4.获得脚本
    /// 5，执行脚本
    /// 6，完成，并上传数据
    /// 7，进入2
    /// </summary>
    public partial class Main : Form
    {
        RASDisplay ras;
        BrowserPipe browserPipe;
        bool loopControl = true;
        int lastTime = 0;

        public Main(Boolean autostartup)
            : this()
        {

        }
        public Main()
        {
            InitializeComponent();
            ras = new RASDisplay();
            browserPipe = new BrowserPipe(this);
            this.mac.Text = Environment.MachineName;


#if DEBUG
            this.logLevel.SelectedIndex = 2;
#else
                this.Shown += new System.EventHandler(this.Main_Shown); 
#endif


        }
        /// 0,检查更新
        /// 1,启动并自动开始
        /// 2.拨号，拨号成功后进入3，失败重播10次，都失败等30分钟
        /// 3，验证，不通过，进入2
        /// 4.获得脚本
        /// 5，执行脚本
        /// 6，完成，并上传数据
        /// 7，进入2
        private void start()
        {
            this.status.Text = "启动";

            int accessError = 0;

            string connName = this.connName.Text;
            int redial = Int16.Parse(this.redial.Text);
            while (loopControl)
            {
                this.logs.Text = "";
                log("String Clear...");
                Helper.clear();
                // 允许访问服务器端时出错10次，
                // 服务器访问出错，就不在拨号了，继续获取数据
                if (accessError == 0 || accessError > 10)
                {
                    accessError = 0;

                    if (!loopControl)
                    {
                        break;
                    }
                    if (ras.Connected() == IntPtr.Zero)
                    {
                        //log("Dial rueslt = " + r);
                        //info.Text += ras.getIPAddress() + "\r\n";
                        //没有拨号成功 ，重拨
                        int r = ras.Connect(connName);
                        //拨号失败等待30秒...
                        waitOfSecond(10);
                    }
                    updateVersion();
                    /////////////清理数据//////////////////////////////// 

                    //if (IntPtr.Zero != ras.Connected())
                    //{
                    //    ras.Disconnect();
                    //}

                    //Application.DoEvents();
                    ////////////////////////////////////////////////////
                    if (!loopControl)
                    {
                        break;
                    }
                    log("Dial Loop Start...");
                    for (int i = 0; i < redial; i++)
                    {
                        if (!loopControl)
                        {
                            break;
                        }
                        if (ras.Connected() == IntPtr.Zero)
                        {
                            //log("Dial rueslt = " + r);
                            //info.Text += ras.getIPAddress() + "\r\n";
                            log("Dial " + (i + 1));
                            //没有拨号成功 ，重拨
                            int r = ras.Connect(connName);
                            //拨号失败等待30秒...
                            waitOfSecond(30 * (i + 1));
                        }
                        else
                        {
                            break;
                        }
                    }
                }

                if (ras.Connected() != IntPtr.Zero)//拨号成功
                {
                    if (accessError == 0)
                    {
                        try
                        {
                            if (!loopControl)
                            {
                                break;
                            }
                            log("Dial OK");
                            /// 3，验证，不通过，进入2
                            /// 4.获得脚本
                            string verify = this.verifyAddr.Text;
                            verify = verify.Replace("{id}", this.mac.Text);
                            verify = verify.Replace("{ip}", ras.getIPAddress());
                            log("verify url = " + verify);

                            Application.DoEvents();

                            if (!loopControl)
                            {
                                break;
                            }
                            int result = Int16.Parse(Helper.SendRequest(verify));
                            log("Verify Result：" + result);
                            /// 0 = ip重复
                            /// 1 = 正常
                            /// 2 = 管理
                            if (result == 0)
                            {
                                log("Verify Status：IP Duplicate");
                                ras.Disconnect();
                                accessError = 0;
                                continue;
                            }
                            else if (result == 2)
                            {
                                log("Verify Status：Machine Manager");
                                waitOfSecond(600);
                                accessError = 1;
                                continue;
                            }
                            else
                            {
                                accessError = 0;
                                // 清理alexa
                                log("Verify Status：Pass");
                                log("Clear Alexa");
                                Helper.GetRegValue("\\HKEY_CURRENT_USER\\Software\\Alexa Internet\\Alexa9\\ALX\\",
                                     "AID", null);
                            }
                        }
                        catch (Exception e)
                        {
                            log(e.ToString(), 3);
                            accessError++;
                        }
                    }

                    try
                    {
                        /// 5，执行脚本
                        //Application.DoEvents();
                        if (!loopControl)
                        {
                            break;
                        }
                        accessError = 0;
                        List<String> script = getJson();

                        log("Scripts Total : " + script.Count + " Time Now = " + DateTime.Now.ToLongTimeString());
                        for (int i = 0; i < script.Count; i++)
                        {
                            if (!loopControl)
                            {
                                break;
                            }
                            log("Execute Script No : " + (i + 1));
                            log(script[i], 2);
                            List<BrowserAction> task = Helper.executeScript(script[i]);
                            if (task == null || task.Count == 0)
                            {
                                continue;
                            }
                            if (script.Count == 1 && task.Count == 1)
                            {
                                log("not task ,so sleep...");
                                accessError = 1;
                            }
                            else
                            {
                                accessError = 0;
                            }
                            browserPipe.process(task);

                            task.Clear();
                            task = null;
                            Application.DoEvents();
                        }

                        script.Clear();
                        script = null;

                        accessError = 0;//成功执行完脚本，就初始化访问错误值
                        /// 6，完成，并上传数据
                        /// 7，进入2

                        ras.Disconnect();
                    }
                    catch (Exception e)
                    {
                        log(e.ToString(), 3);
                        accessError++;
                    }

                }
                else
                {
                    // 拨号失败的处理
                    log("Dial Feil!");
                    waitOfSecond(60 * Int16.Parse(this.timeout.Text));
                }

                GC.Collect();
            }

        }
        /// <summary>
        /// 获得脚本json数据
        /// </summary>
        /// <returns></returns>
        private List<String> getJson()
        {
            string jsinstr = Helper.SendRequest(this.scriptAddr.Text);
            List<String> websiteList = new List<String>();

            System.Runtime.Serialization.Json.DataContractJsonSerializer _Json =
                new System.Runtime.Serialization.Json.DataContractJsonSerializer(websiteList.GetType());
            byte[] _Using = System.Text.Encoding.UTF8.GetBytes(jsinstr);
            System.IO.MemoryStream _MemoryStream = new System.IO.MemoryStream(_Using);
            _MemoryStream.Position = 0;

            return (List<String>)_Json.ReadObject(_MemoryStream);
        }

        /// <summary>
        /// 等待几秒种
        /// </summary>
        /// <param name="second"></param>
        private void waitOfSecond(int second)
        {
            for (int x = 0; x < second && loopControl; x++)
            {
                Application.DoEvents();
                System.Threading.Thread.Sleep(1000);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="t"></param>
        /// <param name="level"></param>
        public void log(string t, int level)
        {
            if (Int16.Parse(this.logLevel.SelectedItem.ToString()) >= level)
            {
                log(t);
            }
        }
        public void log(string t)
        {
            this.logs.AppendText(t + "\r\n");
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.pagedata.Text = Helper.SendRequest(this.url.Text);

        }

        private void button2_Click(object sender, EventArgs e)
        {
            loopControl = true;
            this.start();
        }

        private void button3_Click(object sender, EventArgs e)
        {
            loopControl = false;
            this.status.Text = "停止.";
        }

        private void button4_Click(object sender, EventArgs e)
        {
            browserPipe.process(Helper.executeScript(Regex.Replace(this.clicktest.Text, @"\r\n", "||")));
        }

        private void updateVersion()
        {
            /////////////////////////
            if (lastTime == 0 || lastTime != DateTime.Now.Day)
            {
                log("Check Update...");

                string[] str = Helper.SendRequest(this.updateAddr.Text).Split('|');

                if (str.Count() > 1 && str[1].StartsWith("http"))
                {
                    log("Update...");

                    if (ShouldUpdate(str[0], this.Text))
                    {
                        System.Diagnostics.Process.Start(Application.StartupPath + @"\AutoUpdater.exe",
                            str[1]);
                        this.Close();
                    }
                }

            }

            lastTime = DateTime.Now.Day;

        }

        private bool ShouldUpdate(string serverVersion, string localVersion)
        {
            if (!string.IsNullOrEmpty(serverVersion) && !string.IsNullOrEmpty(localVersion))
            {
                return serverVersion.CompareTo(localVersion) > 0;
            }
            return true;
        }

        private void Main_FormClosing(object sender, FormClosingEventArgs e)
        {
            loopControl = false;
            if (ras != null)
            {
                //ras.Disconnect();
                //if (ras.Connected() == IntPtr.Zero) ras.Connect(this.connName.Text);
                ras = null;
            }
            if (browserPipe != null)
            {
                browserPipe = null;
            }
            Helper.clear();
        }

        private void button5_Click(object sender, EventArgs e)
        {
            MessageBox.Show("IE Version " + Helper.getIEVersion());
        }

        private void button6_Click(object sender, EventArgs e)
        {
            this.logs.Text = "";
        }

        private void button7_Click(object sender, EventArgs e)
        {
            this.pagedata.Text = Helper.GetRegValue("\\HKEY_CURRENT_USER\\Software\\Alexa Internet\\Alexa9\\ALX\\",
               "AID");
        }

        private void button9_Click(object sender, EventArgs e)
        {
            this.pagedata.Text = Helper.GetRegValue("\\HKEY_CURRENT_USER\\Software\\Alexa Internet\\Alexa9\\ALX\\",
                         "AID", "romejiang");
        }

        private void button8_Click(object sender, EventArgs e)
        {
            this.pagedata.Text = Helper.GetRegValue("\\HKEY_CURRENT_USER\\Software\\Alexa Internet\\Alexa9\\ALX\\",
                        "AID", null);
        }

        private void Main_Shown(object sender, EventArgs e)
        {
            this.start();

        }


    }
}
